const Tower = function(n) {
  this.n = n;
  this.t = [[], [], []];
  this.l = [n, 0, 0];
  for (let i = 0; i < this.n; i++) {
    this.t[0][i] = n - i;
  }
};

Tower.prototype.complete = function() {
  return this.l[0] === 0 && this.l[1] === 0;
};

Tower.prototype.canMove = function(from, to) {
  if (this.l[from] === 0) {
    return false;
  }
  if (this.l[to] === 0) {
    return true;
  }
  return this.t[from][this.l[from] - 1] < this.t[to][this.l[to] - 1];
};

Tower.prototype.move = function(from, to) {
  if (this.canMove(from, to)) {
    this.t[to][this.l[to]] = this.t[from][this.l[from] - 1];
    this.l[from]--;
    this.l[to]++;
  }
};

Tower.prototype.print = function() {
  const printPlate = function(pole, plate) {
    if (this.l[pole] <= plate) {
      return '|';
    } else {
      return '' + this.t[pole][plate];
    }
  }.bind(this);
  console.log('');
  for (let i = 0; i < this.n; i++) {
    let line = '';
    line += ' ' + printPlate(0, this.n - 1 - i) + ' ';
    line += ' ' + printPlate(1, this.n - 1 - i) + ' ';
    line += ' ' + printPlate(2, this.n - 1 - i) + ' ';
    console.log(line);
  }
};

Tower.prototype.solve = function(showEachStep) {
  const counter = {count: 0};
  this.step(this.n, 0, 2, counter, showEachStep);
  showEachStep && this.print();
  console.log(counter.count + ' steps were taken');
};

Tower.prototype.step = function(n, from, to, counter, showEachStep) {
  if (n === 1) {
    showEachStep && this.print();
    counter.count++;
    this.move(from, to);
    return;
  }
  const third = 3 - from - to;
  this.step(n - 1, from, third, counter, showEachStep);
  this.step(1, from, to, counter, showEachStep);
  this.step(n - 1, third, to, counter, showEachStep);
};

module.exports = Tower;
